import React, { useState, useCallback, createContext, useContext } from "react";
import styled from "@emotion/styled";
import { motion, AnimatePresence } from "framer-motion";
import {
  FiX,
  FiAlertCircle,
  FiInfo,
  FiCheck,
  FiAlertTriangle,
} from "react-icons/fi";
import { MessageType } from "../tools/common-types";
import {
  zIndex,
  duration,
  easing,
  motionEasing,
  radius,
  spacing,
} from "../utils/design-tokens";

// 样式定义
const ToastContainer = styled.div`
  position: fixed;
  top: ${spacing["5"]};
  right: ${spacing["5"]};
  z-index: ${zIndex.toast};
  display: flex;
  flex-direction: column;
  gap: ${spacing["3"]};
  max-width: 360px;
  pointer-events: none;

  @media (max-width: 768px) {
    top: ${spacing["4"]};
    right: ${spacing["3"]};
    left: auto;
    max-width: calc(100% - ${spacing["3"]} * 2);
    width: auto;
    min-width: 280px;
  }
`;

const ToastItem = styled(motion.div)<{ $type: string }>`
  display: flex;
  align-items: center;
  padding: ${spacing["4"]};
  border-radius: ${radius.lg};
  background-color: var(--bg-primary);
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
    0 4px 6px -2px rgba(0, 0, 0, 0.05);
  color: var(--text-primary);
  border-left: 4px solid
    ${({ $type }) =>
      $type === "success"
        ? "var(--success-border)"
        : $type === "info"
        ? "var(--info-border)"
        : $type === "warning"
        ? "var(--warning-border)"
        : "var(--error-border)"};
  width: 100%;
  pointer-events: auto;

  [data-theme="dark"] & {
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3),
      0 4px 6px -2px rgba(0, 0, 0, 0.2);
  }
`;

const ToastIconWrapper = styled.div<{ $type: string }>`
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: ${spacing["3"]};
  flex-shrink: 0;
  color: ${({ $type }) =>
    $type === "success"
      ? "var(--success-color)"
      : $type === "info"
      ? "var(--info-color)"
      : $type === "warning"
      ? "var(--warning-color)"
      : "var(--error-color)"};
`;

const ToastContent = styled.div`
  flex: 1;
  min-width: 0;
`;

const ToastTitle = styled.div`
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.4;
  margin-bottom: ${spacing["1"]};
`;

const ToastMessage = styled.div`
  font-size: 0.85rem;
  color: var(--text-secondary);
  line-height: 1.5;
  word-break: break-word;
`;

const CloseButton = styled.button`
  background: none;
  border: none;
  color: var(--text-tertiary);
  cursor: pointer;
  padding: ${spacing["1"]};
  margin-left: ${spacing["2"]};
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: ${radius.full};
  transition: all ${duration.fast}ms ${easing.ease};
  flex-shrink: 0;

  &:hover {
    background-color: var(--bg-tertiary);
    color: var(--text-primary);
  }

  &:active {
    transform: scale(0.95);
  }
`;

// 组件接口
export interface ToastProps {
  id: string;
  type: MessageType;
  title?: string;
  message: string;
  duration?: number;
}

type ToastContextType =
  | {
      addToast: (toast: Omit<ToastProps, "id">) => void;
      removeToast: (id: string) => void;
    }
  | undefined;

// Toast上下文
export const ToastContext = createContext<ToastContextType>(undefined);

// 生成唯一ID
const generateId = () =>
  `toast-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;

// Toast提供者组件
export const ToastProvider: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  const [toasts, setToasts] = useState<ToastProps[]>([]);

  const addToast = useCallback((toast: Omit<ToastProps, "id">) => {
    const id = generateId();
    const newToast = { ...toast, id };

    setToasts((prev) => [...prev, newToast]);

    // 自动移除
    if (toast.duration !== 0) {
      setTimeout(() => {
        removeToast(id);
      }, toast.duration || 3000);
    }
  }, []);

  const removeToast = useCallback((id: string) => {
    setToasts((prev) => prev.filter((toast) => toast.id !== id));
  }, []);

  const getIcon = (type: MessageType) => {
    switch (type) {
      case "success":
        return <FiCheck size={20} />;
      case "info":
        return <FiInfo size={20} />;
      case "warning":
        return <FiAlertTriangle size={20} />;
      case "error":
        return <FiAlertCircle size={20} />;
      default:
        return <FiInfo size={20} />;
    }
  };

  return (
    <ToastContext.Provider value={{ addToast, removeToast }}>
      {children}
      <ToastContainer data-toast-container>
        <AnimatePresence>
          {toasts.map((toast) => (
            <ToastItem
              key={toast.id}
              $type={toast.type}
              initial={{ opacity: 0, x: 50, scale: 0.95 }}
              animate={{ opacity: 1, x: 0, scale: 1 }}
              exit={{
                opacity: 0,
                x: 50,
                scale: 0.95,
                height: 0,
                marginBottom: 0,
                overflow: "hidden",
              }}
              transition={{
                duration: duration.fast / 1000,
                ease: motionEasing.spring,
              }}
              layout
            >
              <ToastIconWrapper $type={toast.type}>
                {getIcon(toast.type)}
              </ToastIconWrapper>

              <ToastContent>
                {toast.title && <ToastTitle>{toast.title}</ToastTitle>}
                <ToastMessage>{toast.message}</ToastMessage>
              </ToastContent>

              <CloseButton
                onClick={() => removeToast(toast.id)}
                aria-label="关闭通知"
              >
                <FiX size={18} />
              </CloseButton>
            </ToastItem>
          ))}
        </AnimatePresence>
      </ToastContainer>
    </ToastContext.Provider>
  );
};

// 自定义Hook - 用于组件中使用Toast
export const useToast = () => {
  const context = useContext(ToastContext);

  if (context === undefined) {
    throw new Error("useToast must be used within a ToastProvider");
  }

  return {
    toast: (props: Omit<ToastProps, "id">) => context.addToast(props),
    success: (message: string, title?: string, duration?: number) =>
      context.addToast({ type: "success", message, title, duration }),
    info: (message: string, title?: string, duration?: number) =>
      context.addToast({ type: "info", message, title, duration }),
    warning: (message: string, title?: string, duration?: number) =>
      context.addToast({ type: "warning", message, title, duration }),
    error: (message: string, title?: string, duration?: number) =>
      context.addToast({ type: "error", message, title, duration }),
  };
};

export default { ToastProvider, useToast };
